
#include<iostream>
#include<queue>
#include<vector>
#include<map>
#include<functional>
using namespace std;


struct edge 
{
	int _srci;
	int _dsti;
	int _w;
	edge(int src,int dst,int w)
		:_srci(src),_dsti(dst),_w(w)
	{}
};

//bool operator <(const edge& e1, const edge& e2)
//{
//	return e1._w < e2._w;    
//}

//class unionfindset
//{
//public:
//	unionfindset(int n)
//		:_bs(n, -1)
//	{}
//	bool  Union(int x, int  y)
//	{
//		auto findroot = [&](int x){
//			while (_bs[x] > 0) {
//				x = _bs[x];
//			}
//			return x;
//			};
//		int root1 = findroot(x);
//		int root2 = findroot(y);
//		if (root1 == root2)return false;//如果在一个集合就返回;
//		_bs[root1] += _bs[root2];//否则就合并
//		_bs[root2] = root1;    
//		return true;
//	}
//private:
//	vector<int>_bs;
//};

bool operator>(const edge& e1, const edge& e2) {
	return e1._w > e2._w;   
}


void slove()
{
	int n = 5;
	int m = 7;
	vector<int>bs(n+1, -1);   
	auto Union = [&bs](int x, int y)  
		{
			while (bs[x] > 0)x = bs[x];  
			while (bs[y] > 0)y = bs[y];
			if (x == y)return false;  
			 bs[y] = x;   
			 return true;
		};
	priority_queue<edge, vector<edge>, greater<edge>>q;
	for (int i = 0; i < m; i++)
	{
		int a, b, w;
		cin >> a >> b >> w;
		edge x(a, b, w); 
		q.push(x);   
	}
	int ret = 0;
	while (q.size())
	{
		auto minedge = q.top();
		q.pop();

		if (Union(minedge._srci, minedge._dsti))//如果合并成功就增加权值
			ret += minedge._w;

	}
	cout << ret << endl;    
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	slove();
	return 0;
}

